package com.design.strategy.gplt;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.metadata.Cell;
import com.alibaba.excel.util.StringUtils;
import com.alibaba.fastjson2.JSON;
import com.design.strategy.GpltSettlementDo;
import com.design.strategy.ParseChannelFileRequest;
import com.design.strategy.ParseFileResult;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.util.Assert;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


@Slf4j
public class GpltExcelReadListener extends AnalysisEventListener<GpltSettlementDo> {

    private Integer totalCount;
    private Integer errorCount;
    private Integer BATCH_INSERT_SIZE = 200;
    private ParseFileResult result;
    private ParseChannelFileRequest request;

    public GpltExcelReadListener(Integer totalCount, Integer errorCount, ParseFileResult result, ParseChannelFileRequest request) {
        this.totalCount = totalCount;
        this.errorCount = errorCount;
        this.result = result;
        this.request = request;
    }

    private List<GpltSettlementDo> excelList = Lists.newArrayList();


    @Override
    public void onException(Exception exception, AnalysisContext context) throws Exception {
        String content = "";
        try{
            Object currentRowData = context.readRowHolder().getCurrentRowAnalysisResult();
            content = JSON.toJSONString(currentRowData);
            log.error("解析gplt settlement异常，当前行数据: {}, 异常信息: {}", content, exception);
            Map<Integer, Cell> cellMap = context.readRowHolder().getCellMap();
            String uniqId = cellMap.get(2).toString();  //第三列Unique Id
            if(StringUtils.isBlank(uniqId)) {
                errorCount += 1;
                Assert.hasText(uniqId, "uniqId cannot be null or empty");
                throw new Exception("gplt解析，无法解析到uniqueId字段值");
            }
        } catch (Exception e) {
            log.error("解析gplt settlement异常，当前行数据: {}, 异常信息: {}", content, e);
            errorCount += 1;
            throw new Exception(e);
        }

    }


    @Override
    public void invoke(GpltSettlementDo dto, AnalysisContext context) {
        if(dto == null || StringUtils.isBlank(dto.getUniqueId())) {
            return;
        }
        excelList.add(dto);
        //批量写库
        if (excelList.size() >= BATCH_INSERT_SIZE) {
            totalCount += excelList.size();
            //分组写入
            List<List<GpltSettlementDo>> partition = Lists.partition(excelList, BATCH_INSERT_SIZE);
            for (List<GpltSettlementDo> list : partition) {
                try {
                    //batchInsert(covertBean(list));
                } catch (Exception e) {
                    log.error("解析gplt settlement 批量分组写库异常，异常信息: {}", e);
                    throw e;
                }
            }
            excelList.clear(); //清空，避免大对象占用内存
        }
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        totalCount += excelList.size();
        result.setTotalCount(totalCount);
        result.setErrorCount(errorCount);
        //总条数
        int totalAllCount = totalCount + errorCount;
        log.info("解析gplt settlement 结束，总条数:{}条数据，共解析:{}条数据，失败:{}条数据", totalAllCount, totalCount, errorCount);
        //批量写库
        try {
            if (CollectionUtils.isNotEmpty(excelList)) {
                //batchInsert(covertBean(list));
            }
        } catch (Exception e) {
            log.error("解析gplt settlement 批量写库异常，异常信息: {}", e);
            throw e;
        }

    }

//    private List<ArSettlementReceive> covertBean(List<GpltSettlementDo> excelList) {
//        LocalDateTime createTime = LocalDateTime.now();
//        //设置系统当前时区，比如:GMT+8
//        String SYSTEM_TIME_ZONE = ZonedDateTime.now(ZoneId.of(ZoneId.systemDefault().getId()))
//                .format(DateTimeFormatter.ofPattern("O"));
//        return excelList.stream().map(dto -> {
//            ArSettlementReceive entity = new ArSettlementReceive();  //收款单号，可以自定义生成
//            entity.setId(idGenerator.nextId());
//            entity.setPaymentNo(dto.getPaymentReferenceId());
//            entity.setTransactionId(dto.getPaymentReferenceId()); //外部业务交易号
//            entity.setProjectCode(request.getProjectCode());
//            entity.setChannelSource(request.getChannelSource());
//            entity.setOriginCountry(request.getOriginCountry());
//            entity.setUniqueId(dto.getUniqueId());
//            entity.setPaymentReferenceId(dto.getPaymentReferenceId());
//            entity.setParentPaymentReferenceId(dto.getParentPaymentReferenceId());
//            entity.setShipmentId(dto.getShipmentId());
//            entity.setTrackingId(dto.getTrackingId());
//            entity.setTransactionType(dto.getTransactionType());
//            entity.setTransactionCode(dto.getTransactionCode());
//            entity.setCustomerId("2523664");  //todo 客户编码
//            entity.setCustomerName("张三");  //todo 客户名称
//            entity.setStatus("1");
//            entity.setSettlementDate(parseDate(dto.getSettlementDate()));
//            entity.setSettlementTime(dto.getSettlementTime());
//            //设置收款时间
//            entity.setPayoutDate(parseDate(dto.getPayoutDate()));
//            entity.setPayoutTime(dto.getPayoutTime());
//            LocalDate payoutDate = LocalDate.from(entity.getPayoutDate());
//            String paymenTimeStr = payoutDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) + " " + dto.getPayoutTime();
//            entity.setPaymentTime(DateUtil.ofLocalDateTime(paymenTimeStr, "yyyy-MM-dd HH:mm:ss"));
//            entity.setPaymentTimeZone(SYSTEM_TIME_ZONE);
//            entity.setTransactionCode(dto.getTransactionCode());
//            entity.setDrCr(dto.getDrCrForPayment());
//            entity.setReversalFlag(dto.getReversalFlag());
//            entity.setGrossAmount(getAmount(dto.getGrossAmount()));
//            entity.setNetAmount(getAmount(dto.getNetAmount()));
//            entity.setCurrency(dto.getPaymentCurrency());
//            entity.setDrCrForFee(dto.getDrCrForFee());
//            entity.setFeeAmount(getAmount(dto.getFeeAmount()));
//            entity.setFeeCurrency(dto.getFeeCurrency());
//            entity.setCreateTime(createTime);
//            entity.setCreateUserCode(ApplicationConstants.SYSTEM_OPERATOR);
//            entity.setModifyTime(createTime);
//            entity.setModifyUserCode(ApplicationConstants.SYSTEM_OPERATOR);
//            entity.setIsActive(ApplicationConstants.ACTIVE);
//            return entity;
//        }).collect(Collectors.toList());
//    }

    /**
     * 日期转换
     * @param date
     * @return
     */
    private static LocalDateTime parseDate(String date) {
        if (StringUtils.isNotBlank(date)) {
            return LocalDate.parse(date, DateTimeFormatter.ofPattern("dd/MM/yyyy")).atStartOfDay();
        }
        return null;
    }

    /**
     * 金额转换 (字符串转BigDecimal)
     * @param amount
     * @return
     */
    private static BigDecimal getAmount(String amount) {
        if (StringUtils.isNotBlank(amount)) {
            return new BigDecimal(amount);
        }
        return null;
    }

}
